#include "../include/list.h"
#include <stdlib.h>
#include <stdio.h>

List createList(void *data){
  Node* node = (Node *) malloc(sizeof(Node));    /* allocation et affectation à la variable list */
  if(node == NULL){
    fprintf(stderr, "Problème de création de Noeud.\n");
    return NULL;
  }
  node->data = data;                          /* affectation du champ data */
  node->next = NULL;                          /* affectation du champ next à la liste vide */
  return node;                                /* retour de la liste (correctement allouée et affectée ou NULL) */
}

List prependList(List old, void *data){
  List list = createList(data); 	  /* création et affectation d'une liste d'un élément */
  if(list){                       	/* si l'allocation mémoire a réussi */
    list->next = old;             	/* accrochage de l'ancienne liste à la nouvelle */
  }
  return list;                    	/* retour de la nouvelle liste (ou NULL si l'allocation a échoué) */
}

List appendList(List list, void *data){
  List *plist = &list;
  while(*plist){
    plist = &(*plist)->next;
  }
  *plist = createList(data);
  if(*plist){
    return list;
  }
  else{
    fprintf(stderr, "Le noeud n'a pas pu être crée.\n");
    return NULL;
  }
}

List removeFirstList(List list){
    if(list == NULL){
        fprintf(stderr, "removeFirstList::list n'existe pas\n");
        return NULL;
    }
    Node *first = list; 	  /* conservation de la liste actuelle */
    list = list->next;  	/* faire pointer list sur le reste */
    free(first->data);
    first->data = NULL;
    free(first);        	/* libérer la mémoire utilisée par la structure List précédente */
    first = NULL;
    return list;        	/* retour de la nouvelle liste */
}

List removeFromList(List list, void *data){
    if(list == NULL){
        fprintf(stderr, "removeFromList::list n'existe pas.\n");
        return NULL;
    }
    if(data == NULL){
        fprintf(stderr, "removeFromList::data n'existe pas\n");
        return list;
    }
    if(data == list->data){
        return removeFirstList(list);
    }
    Node *prev = list;
    Node *curr = list->next;
    while(curr != NULL && curr->data != data){
        prev = curr;
        curr = curr->next;
    }
    if(curr->data == data){
        prev->next = removeFirstList(curr);
    }
    return list;
}

int lengthList(List list){
  int length = 0;        	  /* initialisation de la longueur à 0 */
  while(list){              /* tant que la fin de la liste d'est pas atteinte */
    length++;          	    /* incrémenter la longueur */
    list = list->next; 	    /* passer à l'élément suivant */
  }
	return length;       	    /* retourner la longueur calculée */
}

void printList(List list){
	Node *tmp;
	if(list == NULL){
		printf("La list est NULL\n");
		return;
	}
	tmp = list;
	while(tmp != NULL){
		printf("node: %p value: %p next: %p\n", tmp, tmp->data, tmp->next);
		tmp = tmp->next;
	}
}

void freeList(List list){
  while (list){	                      /* tant que l'on n'est pas arrivé en fin de liste */
    list = removeFirstList(list); 	/* retrait du premier élément de la liste */
	}
}

